﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using ControleRepresentante.Logic.Models;
using ControleRepresentante.Logic.Statistics;
using WebSite.Controllers;
using WebSite.ViewModels.Fields;

namespace WebSite.ViewModels.IndexViewModels
{
    public static class PedidoIndexColumns
    {
        public static Guid Data = new Guid("48a072fb-ea6d-4126-9dff-6fe820919ff8");
        public static Guid Numero = new Guid("9ac621ed-4b3d-407b-9dc8-837ba3d31f2d");
        public static Guid Cliente = new Guid("d09b83b3-0d0f-4a3a-b3aa-b4f3c33d4f51");
        public static Guid Vendedor = new Guid("1688a729-9414-4e32-b8bb-156164da8caf");
        public static Guid Fabrica = new Guid("cc8b9dcb-4418-4f12-9761-a3fcd90f4689");
        public static Guid Transportadora = new Guid("a78243b8-6dba-407a-903a-03acd8c77f4a");
        public static Guid TotalMercadoria = new Guid("3d2da3dc-b84f-4f77-b4ae-03b4003269dd");
        public static Guid Faturado = new Guid("8cfe87e9-d9b7-4210-be30-4e57e573abbf");
        public static Guid Cancelado = new Guid("cfea9fbd-0fce-468f-a54a-ca2f6ef28063");
        public static Guid ValorDesconto = new Guid("19a7a884-11d1-42f6-bfa4-57c5efa8c411");
        public static Guid Desconto = new Guid("c23fcc7b-cfbc-41df-bf84-09ff2a8426c0");
        public static Guid CondicaoPagamento = new Guid("bcf35a16-7c89-4630-bdc1-b2bbf277d458");
        public static Guid PrazoEntrega = new Guid("0e6faf6a-4ec4-4c8a-a0e4-a35c5b35057b");
        public static Guid Observacao = new Guid("867b719f-759f-4bfb-8244-0471dfcdeead");
        public static Guid TotalPecas = new Guid("655aad90-5839-4ba6-84fc-7cfcfebbf7fe");
        public static Guid Criado = new Guid("4FCB6DAB-829B-4F4C-AFFF-158A6E2D3385");
        public static Guid Modificado = new Guid("5FCECDAC-1024-4006-A301-0A306DFE9885");
    }

    public class PedidoIndexViewModel : AttributeHolderIndexViewModel<Pedido>
    {
        private readonly bool m_CanViewCliente;
        private readonly bool m_CanViewVendedor;
        private readonly bool m_CanViewFabrica;
        private readonly bool m_CanViewTransportadora;
        private readonly bool m_CanPrint;
        private readonly PedidoStatistics m_Statistics;

        public Dictionary<Guid, string> VendedorBusca { private get; set; }
        public Dictionary<Guid, string> FabricaBusca { private get; set; }
        public Dictionary<Guid, string> TransportadoraBusca { private get; set; }

        public int? NumeroBuscaValue { private get; set; }
        public string VendedorBuscaValue { private get; set; }
        public string ClienteBuscaValue { private get; set; }
        public string FabricaBuscaValue { private get; set; }
        public string TransportadoraBuscaValue { private get; set; }
        public DateTime? DeBuscaValue { private get; set; }
        public DateTime? AteBuscaValue { private get; set; }
        public double? TotalMinBuscaValue { private get; set; }
        public double? TotalMaxBuscaValue { private get; set; }
        public string ObservacaoBuscaValue { private get; set; }
        public bool? FaturadoBuscaValue { private get; set; }
        public bool? CanceladoBuscaValue { private get; set; }
        public int? NumeroProdutosBuscaValue { private get; set; }
        public int? NumeroPecasBuscaValue { private get; set; }
        public string DescricaoProdutoBuscaValue { private get; set; }
        public DateTime? CriadoDeBuscaValue { private get; set; }
        public DateTime? CriadoAteBuscaValue { private get; set; }
        public DateTime? ModificadoDeBuscaValue { private get; set; }
        public DateTime? ModificadoAteBuscaValue { private get; set; }

        public PedidoIndexViewModel(bool canViewCliente, bool canViewVendedor, bool canViewFabrica, bool canViewTransportadora, bool canPrint, PedidoStatistics statistics)
            : base("Pedidos")
        {
            m_CanViewCliente = canViewCliente;
            m_CanPrint = canPrint;
            m_Statistics = statistics;
            m_CanViewTransportadora = canViewTransportadora;
            m_CanViewFabrica = canViewFabrica;
            m_CanViewVendedor = canViewVendedor;
        }

        protected override void RegisterColumns(IndexColumnDefinitionsCollectionWrapper<Pedido> indexColumnDefinitionsCollectionWrapper)
        {
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Data, pedido => pedido.Data);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Numero, (pedido, htmlHelper) => htmlHelper.ActionLink(pedido.Numero.ToString(), "Details", new { id = pedido.Id }));
            Func<Pedido, HtmlHelper, object> clienteTemplate;
            if (m_CanViewCliente)
            {
                clienteTemplate = (pedido, htmlHelper) =>
                {
                    return htmlHelper.ActionLink(pedido.ClienteNome, "Details", "Cliente", new { id = pedido.Cliente.Id }, null);
                };
            }
            else
            {
                clienteTemplate = (pedido, htmlHelper) => pedido.ClienteNome;
            }
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Cliente, clienteTemplate);
            if (m_CanViewVendedor)
            {
                indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Vendedor, (Func<Pedido, HtmlHelper, object>) ((pedido, htmlHelper) => htmlHelper.ActionLink(pedido.VendedorNome, "Details", "Vendedor", new { id = pedido.Vendedor.Id }, null)));
            }
            Func<Pedido, HtmlHelper, object> fabricaTemplate;
            if (m_CanViewFabrica)
            {
                fabricaTemplate = (pedido, htmlHelper) =>
                {
                    return htmlHelper.ActionLink(pedido.FabricaNome, "Details", "Fabrica", new { id = pedido.Fabrica.Id }, null);
                };
            }
            else
            {
                fabricaTemplate = (pedido, htmlHelper) => pedido.FabricaNome;
            }
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Fabrica, fabricaTemplate);
            Func<Pedido, HtmlHelper, object> transportadoraTemplate;
            if (m_CanViewTransportadora)
            {
                transportadoraTemplate = (pedido, htmlHelper) =>
                {
                    return htmlHelper.ActionLink(pedido.TransportadoraNome, "Details", "Transportadora", new { id = pedido.Transportadora.Id }, null);
                };
            }
            else
            {
                transportadoraTemplate = (pedido, htmlHelper) => pedido.TransportadoraNome;
            }
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Transportadora, transportadoraTemplate);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.TotalMercadoria, pedido => String.Format("{0:C}", pedido.TotalMercadoria));
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.ValorDesconto, pedido => String.Format("{0:C}", pedido.ValorDesconto));
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Desconto, pedido => String.Format("{0:0.0}%", pedido.Desconto));
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Faturado, pedido => pedido.Faturado);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Cancelado, pedido => pedido.Cancelado);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.CondicaoPagamento, pedido => pedido.CondicaoPagamento);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.PrazoEntrega, pedido => pedido.PrazoEntrega);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Observacao, pedido => pedido.Observacao);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.TotalPecas, pedido => pedido.TotalPecas);
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Criado, pedido => String.Format("{0} {1}", pedido.Created.ToShortDateString(), pedido.Created.ToShortTimeString()));
            indexColumnDefinitionsCollectionWrapper.Register(PedidoIndexColumns.Modificado, pedido => String.Format("{0} {1}", pedido.Modified.ToShortDateString(), pedido.Modified.ToShortTimeString()));

            base.RegisterColumns(indexColumnDefinitionsCollectionWrapper);
        }

        protected override IEnumerable<ButtonType> ButtonTypes(Pedido modelBase)
        {
            List<ButtonType> result = new List<ButtonType>(base.ButtonTypes(modelBase));
            if (CanCreate)
            {
                result.Add(ButtonType.Duplicate);
            }
            if (m_CanPrint)
            {
                result.Add(ButtonType.Print);
            }
            return result;
        }

        protected override IEnumerable<IField> GetSearchFields()
        {
            yield return new TextBoxField("Número", "numero", NumeroBuscaValue);
            if (m_CanViewVendedor)
            {
                yield return new TokenInputField("Vendedores", "vendedorIds", VendedorBuscaValue, "Search", "SearchVendedor", VendedorBusca);
            }
            yield return new AutoCompleteField("Clientes", "cliente", ClienteBuscaValue, "SearchCliente", "Search");
            if (m_CanViewFabrica)
            {
                yield return new TokenInputField("Fábricas", "fabricaIds", FabricaBuscaValue, "Search", "SearchFabrica", FabricaBusca);
            }
            yield return new TokenInputField("Transportadoras", "transportadoraIds", TransportadoraBuscaValue, "Search", "SearchTransportadora", TransportadoraBusca);
            yield return new DatePickerField("De", "de", DeBuscaValue);
            yield return new DatePickerField("Até", "ate", AteBuscaValue);
            yield return new DatePickerField("Criado de", "criadoDe", CriadoDeBuscaValue);
            yield return new DatePickerField("Criado até", "criadoAte", CriadoAteBuscaValue);
            yield return new DatePickerField("Modificado de", "modificadoDe", ModificadoDeBuscaValue);
            yield return new DatePickerField("Modificado até", "modificadoAte", ModificadoAteBuscaValue);
            yield return new TextBoxField("Total Mínimo (R$)", "totalMin", TotalMinBuscaValue);
            yield return new TextBoxField("Total Máximo (R$)", "totalMax", TotalMaxBuscaValue);
            yield return new TextBoxField("Numero de Produtos", "numeroProdutos", NumeroProdutosBuscaValue);
            yield return new TextBoxField("Numero de Peças", "numeroPecas", NumeroPecasBuscaValue);
            yield return new TextBoxField("Descriçao de Produto", "descricaoProduto", DescricaoProdutoBuscaValue);
            yield return new DropDownListField("Faturado", "faturado")
                .AddEmpty(!FaturadoBuscaValue.HasValue)
                .Add("Sim", true, FaturadoBuscaValue == true)
                .Add("Não", false, FaturadoBuscaValue == false);
            yield return new DropDownListField("Cancelado", "cancelado")
                .AddEmpty(!CanceladoBuscaValue.HasValue)
                .Add("Sim", true, CanceladoBuscaValue == true)
                .Add("Não", false, CanceladoBuscaValue == false);
            yield return new TextBoxField("Observação", "observacao", ObservacaoBuscaValue);

            foreach (IField field in base.GetSearchFields())
            {
                yield return field;
            }
        }

        protected override IEnumerable<TabItem> GetTabs(HtmlHelper htmlHelper)
        {
            List<TabItem> result = new List<TabItem>
            {
                new TabItem("Estatísticas", "~/Content/statistics.png", new FormLayoutViewModel(htmlHelper)
                    .AddField(new LabelField("Total", "total", m_Statistics.ModelCount))
                    .AddField(new LabelField("Peças", "pecas", m_Statistics.Pecas))
                    .AddField(new LabelField("Valor Total", "valorTotal", String.Format("{0:C}", m_Statistics.ValorTotal)))
                    .AddField(new LabelField("Valor Médio", "valorMedio", String.Format("{0:C}", m_Statistics.ValorMedio)))
                    .AddField(new LabelField("Porcentagem", "porcentagem", String.Format("{0:0.0}%", m_Statistics.Porcentagem))))
            };

            if (m_CanViewVendedor)
            {
                ChartSeries vendedores = new ChartSeries("Vendedores", m_Statistics.Vendedores);
                result.Add(new TabItem("Vendedores", "~/Content/statistics.png", htmlHelper.GooglePieChart(null, vendedores, true)));
            }

            if (m_CanViewFabrica)
            {
                ChartSeries fabricas = new ChartSeries("Fabricas", m_Statistics.Fabricas);
                result.Add(new TabItem("Fabricas", "~/Content/statistics.png", htmlHelper.GooglePieChart(null, fabricas, true)));
            }

            result.AddRange(base.GetTabs(htmlHelper));
            return result;
        }
    }
}